package znet

import (
	logging "github.com/sirupsen/logrus"
	"webdemo/src/zinx/utils"
	"webdemo/src/zinx/zinterface"
)

type MsgHandle struct {
	Apis           map[uint32]zinterface.IRouter
	TaskQueue      []chan zinterface.IRequest
	WorkerPoolSize uint32
}

func NewMsgHandle() *MsgHandle {
	return &MsgHandle{
		Apis:           make(map[uint32]zinterface.IRouter),
		WorkerPoolSize: utils.GlobalObj.WorkerPoolSize,
		TaskQueue:      make([]chan zinterface.IRequest, utils.GlobalObj.WorkerPoolSize),
	}
}

func (m *MsgHandle) DoMsgHandler(request zinterface.IRequest) {
	router, ok := m.Apis[request.GetDataId()]
	if !ok {
		logging.Error("[MsgHandle][DoMsgHandler] msgId is err ")
	}
	router.PreHandle(request)
	router.Handle(request)
	router.PostHandle(request)
}

func (m *MsgHandle) AddRouter(msgId uint32, router zinterface.IRouter) {
	if _, ok := m.Apis[msgId]; ok {
		// 已注册
		logging.Error("[MsgHandle][AddRouter] repeat")
		return
	}
	m.Apis[msgId] = router
	logging.Info("[MsgHandle][AddRouter] success")
}

// worker 工作池
func (mh *MsgHandle) StartWorkerPool() {
	logging.Info("[MsgHandle][StartWorkerPool] start...")
	for i := 0; i < int(mh.WorkerPoolSize); i++ {
		mh.TaskQueue[i] = make(chan zinterface.IRequest, utils.GlobalObj.MaxWorkerTaskLen)
		go mh.StartOneWorker(i, mh.TaskQueue[i])
	}
}

// work工作流程
func (mh *MsgHandle) StartOneWorker(workerId int, taskQueue chan zinterface.IRequest) {
	logging.Info("[MsgHandle][StartOneWorker] start,workerId is ", workerId)
	for {
		select {
		case request := <-taskQueue:
			mh.DoMsgHandler(request)
		}
	}
}

func (mh *MsgHandle) SendMsgToTaskQueue(request zinterface.IRequest) {
	// 将消息平均分配到不同worker
	workerId := request.GetConnection().GetConnID() % mh.WorkerPoolSize
	logging.Info("[MsgHandle][SendMsgToTaskQueue] start,workerId is ", workerId)

	// 消息发送到对应worker的 taskqueue
	mh.TaskQueue[workerId] <- request
}
